// 1.using声明和using编译指令
// using声明使特定的标识符可用,C++提供了两钟机制用来简化命名空间的使用,除非你想一直使用类似于 Jill::fetch() 这样的;
// 一种是using声明,一种是using 编译指令
// using声明是这样的:

namespace Jill
{
    char name;
    int age;
}


// 这样的就是using声明,他会使声明的具体内容可用(这里是name)
// using Jill::name;

// 加上namespace的就是using编译指令
// using namespace Jill;
// 像上面的直接在根作用域下的属于全局名称空间,如果在函数中的using

// 2.using声明和using编译指令的区别
// 如果使用在函数中using那么将会对函数生效
// 使用using namespace将会将空间中的所有的名称都引入你想要使用的作用域中

// 一般是这样使用的
// 先include,把命名空间包含
#include <iostream>
// 使用你需要的命名空间的名称(当然你自己使用std::cout << "....." << std::endl; 当我没说)
using std::cout;
using std::endl;

int age = 20;
int main(int argc, char const *argv[])
{
    // int age = 10;
    // using Jill::age;
    // 上面两个age将不会通过编译,因为同一个函数空间中不会出现同一个

    using Jill::age; // 如果使用using编译指令导入一个已经存在的名称,则局部名称将会隐藏名称空间名,就像局部变量隐藏全局变量一样
    age = 30;        // 这里使用的age是 Jill中的age,如果想使用函数外的全局age,请使用全局::,像下面这样

    cout << "Jill::age = " << Jill::age << endl;
    cout << "global age = " << ::age << endl;
    // 通常来说使用using声明比使用using编译指令更加安全,因为只导入特定的名称

    return 0;
}

// 3.嵌套命名空间
namespace elements
{
    namespace fire
    {
        int flame;
        // ...
    }
    float water;
}
// 如果想使用flame,请使用 elements::fire::flame;

// 同样的可以在命名空间中使用using
namespace mynamespace
{
    using Jill::age;
    using namespace elements;
    using std::cout;
}
// 可以通过这样的方式进行访问:
// std::cout << mynamespace::age;           // 因为Jill::age现在在mynamespace中,所以通过mynamespace::age进行访问

// 当using namespace mynamespace之后,其中的elements也被using,elements中的fire也被using!!!
// 这样可以为名称空间创建别名,类似于
namespace MyNameSpace = mynamespace;
namespace MY_Elem_Fire = MyNameSpace::fire;
using MY_Elem_Fire::flame;


// 4.没有名字的命名空间
// 无名命名空间，又称为未命名的命名空间。是指关键字namespace后紧跟花括号括起来的一系列声明语句，不需要对命名空间取名
namespace 
{
    int none;
    char noName;
}
// 无名命名空间中定义的变量拥有同静态变量一样的生命周期，在第一次使用前创建，直到程序结束才销毁,从这个方面来看,和全局变量相似
// 无名命名空间的成员可以在所定义的文件中直接使用。不需要使用命名空间的名字进行作用域限定，因为无名命名空间没有名字可以用来限定
// 不能在未命名名称空间所处的文件之外的其他文件中使用这种名称空间
// 使用无名命名空间可以替代文件中的静态声明。在文件中进行静态声明的做法已经被C++标准取消，推荐的做法是使用无名命名空间
